<?php
/* class represents the blog itself */
class blog{	
	// private handle for the db
	public $db;
	
	/* constructor loads the blog */
	function __construct($domain){
		// instanciate the database class
		$this->db = new database();
		
		// set the site id to use with this site
		$site_id = $this->db->getSiteIdByDomain($domain);
		if($site_id==-1){
			// redirect the client to the default site when
			// the domain is not configured in the system
			$default_domain = $this->db->getDefaultDomain();
			if(strlen($default_domain)>0){
				// redirect the user to the default domain
				header("HTTP/1.1 301 Moved Permanently"); 
				header("Location: http://".$default_domain."/"); 
				header("Connection: close"); 
			}else{
				// die when this config failure occurs
				die("DOMAIN UNCONFIGURED AND "
					."NO DEFAULT DOMAIN EXISTS");
			}
		}else{
			// set the site id in the database class for further use
			$this->db->setSite($this->db->getSiteIdByDomain($domain));
			
			// set the language for this site and just use
			// the first item in the language list as currently
			// our system does not support multi-language sites
			// and instead the recommend implementation is to have
			// a separate site for each language as the culture and
			// user behaviour also changes - nevertheless the db
			// is prepared to have that one day maybe.
			$langList = $this->db->getLanguageList();
			$this->db->setLanguageCode($langList[0]["code"]);
			
			// finally set the global configuration
			$this->setGlobalConfiguration();
		}
	}
	
	/* this method retrieves all settings from the database 
	 * and updates the configuration for the site by setting 
	 * the global configuration setting using <define()> */
	private function setGlobalConfiguration(){
		// read all settings from the database
		$settings = $this->db->getSettingList();
		for($s=0;$s<count($settings);$s++){
			// TIMEZONE requires a different call than <define()>
			if($settings[$s]["code"]=="TIMEZONE"){
				if(strlen($settings[$s]["value"])>0){
					// update the timezone
					date_default_timezone_set($settings[$s]["value"]);
				}
			}
			// the locale requires a different call as well
			if($settings[$s]["code"]=="LCTIME"){
				setlocale(LC_TIME, $settings[$s]["value"]);
			}
			// only set the global constant when its 
			// not yet defined elsewhere in the config.php f.e.
			$constantConfigName = "CONFIG_".$settings[$s]["code"];
			if(!defined($constantConfigName)){
				// use define to set the global config value
				define($constantConfigName,$settings[$s]["value"]);
			}
		}
	}
	
	// adds a facebook user to the database
	public function addFacebookUser($user){
		/* inserts or updates the user in the database */
		$this->db->addUser($user->username, "fb_".$user->id, 
				$user->first_name, $user->last_name, "", false);
	}
	
	/* returns the latest articles where the param defines
	 * how many of the latest articles should be returned */
	public function getLatestArticles($articleCount){
		$result = array();
		$list = $this->db->getArticleList();
		$max = $articleCount;
		
		/* decrease the number when there are not
		 * sufficient articles in the result list */
		if(count($list)<$max){
			$max = count($list);
		}
		
		$r = 0;
		for($a=0;$a<$max;$a++){
			/* check if the articles is already published */
			if($list[$a]["published"]=="1" && $list[$a]["date_ts"] < time()){
				$result[$r] = $list[$a];
				$r++;
			}
		}
		return $result;
	}
	
	/* returns the article for the url */
	public function getArticle($article,$preview = false){
		$result = null;
		$list = $this->db->getArticleList();
		for($a=0;$a<count($list);$a++){
			if($list[$a]["url"]==$article && ($list[$a]["date_ts"] < time() || $preview==true)){
				if($list[$a]["published"]=="1" || $preview == true){
					// this is the requested article and
					// it already is active and published
					// or we are in preview mode
					$result = $this->db->getArticle($list[$a]['url']);

					// prepare the body for publishing
					$result["formatted_body"] = $this->prepareArticleBody($result["body"]);
				}
			}
		}
		return $result;
	}
	
	/* this method changes the body by adding image 
	 * host names for the different CDN servers on which
	 * the images are located */
	public function updateCdnHtml($body){
		$result = $body;
		$hostlist = explode(";", CONFIG_CDN_IMG_DOMAIN);
		preg_match_all("|src=\"([^>]*)\.([jpgnif]{3})\"|U", $result, $found);
		if(count($found)>0){
			$h = 0;
			for($i=0;$i<count($found[0]);$i++){
				if($h>=count($hostlist)){
					$h=0;
				}
				
				if(substr($found[0][$i],0,6)=="src=\"/"){
					$oldVal = $found[0][$i];
					$newVal = str_replace("src=\"", "src=\"http://"
									.$hostlist[$h], $found[0][$i]);
					$result = str_replace($oldVal, $newVal, $result);
				}
				
				$h++;
			}
		}
	
		return $result;	
	}
	
	/* determines the feature image for this article 
	 * and returns its path */
	public function getArticleImage($body){
		$result = "";
		
		/* remove all slashes that might exist */
		$aBody = stripslashes($body);
		
		/* regexp match all image tags in the body */
		preg_match_all("|<img style=\"([^>]*)\" src=\"([^>]*)\" alt=\"([^>]*)\" "
						."width=\"([^>]*)\" height=\"([^>]*)\" />|U", $aBody, $found);
						
		/* replace all image tags with the updated url that contains the 
		 * image name for the server-side image scaler */
		for($i=0; $i<count($found[2]);$i++){
			// only take the first image that appears
			if(strlen($result)==0){
				$result = substr($found[2][$i],strrpos($found[2][$i], "/")+1);
			}
		}
		
		// return the image
		return $result;
	}
	
	/* replaces image tags and their url with the correct 
	 * name of the script that properly resizes them on 
	 * the server side. Also prepares existing code blocks
	 * to be rendered correctly with syntax highlighting */
	private function prepareArticleBody($articleBody){
		// database in production might have slashes in there
		$result = stripslashes($articleBody);
		
		/* regexp match all image tags in the body */
		preg_match_all("|<img style=\"([^>]*)\" src=\"([^>]*)\" alt=\"([^>]*)\" "
						."width=\"([^>]*)\" height=\"([^>]*)\" />|U", $result, $found);
						
		/* replace all image tags with the updated url that contains the 
		 * image name for the server-side image scaler */
		for($i=0; $i<count($found[2]);$i++){
			$filename = substr($found[2][$i],strrpos($found[2][$i], "/")+1);	
			$filetitle = substr($filename,0,strrpos($filename, "."));
			$fileext = substr($filename,strrpos($filename, "."));
			$new_filename = "/img/".$filetitle."_".$found[4][$i].$fileext;
			
			$updated_tag = "<a href=\"/img/".$filename."\" border=\"0\" target=\"_blank\">"
						."<img style=\"".$found[1][$i]."\" src=\"".$new_filename
						."\" alt=\"".$found[3][$i]."\" /></a>";
			$result = str_replace($found[0][$i], $updated_tag, $result);
		}
		
		return $result;
	}
	
	/* returns all articles for the category */
	public function getCategoryArticles($category){
		$result = array();
		
		// load the article and their categories
		$ac_list = $this->db->getArticleCategoryList();
		
		// get all active articles for this category
		$r=0;
		for($ac=0;$ac<count($ac_list);$ac++){
			// check if its the category requested
			if($ac_list[$ac]["category_url"]==$category){
				// make sure the article is active
				if($ac_list[$ac]["article_published"]=="1"
					&& $ac_list[$ac]["article_date_ts"] < time()){
					// this is active, add it
					$result[$r] = array();
					$result[$r]["title"] = $ac_list[$ac]["article_title"];
					$result[$r]["date"] = $ac_list[$ac]["article_date"];
					$result[$r]["date_ts"] = $ac_list[$ac]["article_date_ts"];
					$result[$r]["url"] = $ac_list[$ac]["article_url"];
					$r++;
				}	
			}
		}
		
		return $result;
	}
}
?>
